package cn.geewallet.util;

import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.geewallet.exception.GeewalletClientException;
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.digest.MD5;


/**
 * <P>AES加解密</P>
 * 
 * @version $Id$
 * @user xzp 2018年12月13日 下午6:53:55
 */
public class AESUtils {

	private final static Logger log = LoggerFactory.getLogger(AESUtils.class);

	/**
	 * 密钥算法
	 */
	private static final String ALGORITHM = "AES";
	/**
	 * 加解密算法/工作模式/填充方式
	 */
	private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS7Padding";

	static {
		try {
			Security.addProvider(new BouncyCastleProvider());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	 /**
     * 生成符合AES要求的密钥, 长度为256位.
     */
    public static String generateAesKey() throws NoSuchAlgorithmException {
        KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM);
        //下面调用方法的参数决定了生成密钥的长度，可以修改为128, 192或256
        kg.init(256);
        SecretKey sk = kg.generateKey();
        byte[] secretKey = sk.getEncoded();
        return Base64.encode(secretKey);
    }
    
	/**
	 * AES加密
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static String encryptData(String data, String keyStr) throws GeewalletClientException {
		try {
			// 创建密码器
			Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
			// 初始化
			SecretKeySpec key = new SecretKeySpec(MD5.create().digestHex(keyStr).toLowerCase().getBytes(), ALGORITHM);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			return Base64.encode(cipher.doFinal(data.getBytes()));
		} catch (Exception e) {
			log.error("AES加密失败encryptData", e);
			throw new GeewalletClientException("AES加密失败,encryptData:" + e.getMessage());
		}
	}

	/**
	 * AES解密
	 */
	public static String decryptData(String base64Data, String keyStr) throws GeewalletClientException {
		try {
			Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);
			SecretKeySpec key = new SecretKeySpec(MD5.create().digestHex(keyStr).toLowerCase().getBytes(), ALGORITHM);
			cipher.init(Cipher.DECRYPT_MODE, key);
			return new String(cipher.doFinal(Base64.decode(base64Data)));
		} catch (Exception e) {
			log.error("AES解密失败decryptData", e);
			throw new GeewalletClientException("AES解密失败,decryptData:" + e.getMessage());
		}
	}


	public static void main(String[] args) throws Exception {
		try {
			String testde = AESUtils.encryptData("5161396000020749", "DHPok7HhFnNUkhez/m9yhw==QFjtt2OikJ/GkNMoTMrytw==");
			System.out.println(testde);
			System.out.println(AESUtils.decryptData("osbZf4zsSZ2NVkoQUosP1ZkNLSJAMYj2SfUGnG+tDc4=", "DHPok7HhFnNUkhez/m9yhw==QFjtt2WqnJ/GkNjTdMrytw=="));

			// System.out
			// .println("cardNo:" + AESUtils.encryptData5("{\"code\":\"00\",\"msg\":\"成功\"}",
			// "0123456789abcdef")); // 加密
			// System.out.println("exp:" + AESUtils.decryptData5(
			// "IgVXDyReWEj4qOEtoVWf7K36a+SpRe8zmbRbouki/kcJGSoRYqmhznvA7nF86DEIfB+XYUX6vLRyMP4CoqPiWHGW3WOquAUF1QlEH6ZR9HqDEucT65lqhMzAmk6Sxv6TRLySWjffjmN0VS1iIfyNF5+jR9LmFjrY6neoEErUHjlsyZBqLlDDtYFy4hlLSGTfFLNnus/WfDaAmevq7tBwlJUBkRX2MU9FlQ2YzOHpQ369mNOAspbIiWgA5MQXlCqjdiOq22q653udLhfwOhA3+TKUEju4pS05EYG3JQtmN8aMQtCj6xJCQPP/YAp+AIpJ1dqIAdqvoSKGUQEWYLNaGJsnBrq2yS/PeyNYGBSzic5QTb+nsZVrUB+wLp68qjZUtqr/cvcpwB1I4kKHrfS45SCkJ8PtSeIUHdOE+m+F2sSET2KBB2nQHsIEy/IVJ1xXI2LDgPhBtnQWLirt6jzIOFy5xXltaUou5hp0NPmMR+LzyFYB86QN3v7Hcr4rt0zVN/aoBo2BuSWu5cFkiBJrOPu34N5VSZRznqL/asOSqgLxWlVKiGyZnrJp/HqLQ5QD",
			// "0123456789abcdef")); // 解密
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
